<template>
  <div id="SingleText" v-loading="loading">
    <!-- 文本输入框 -->
    <el-row type="flex" class="row-bg" justify="center">
      <el-col :span="20">
        <el-row class="el-row-stype">
          <div class="grid-content bg-purple">
            <el-input
              type="textarea"
              :autosize="{ minRows: 5, maxRows: 20 }"
              placeholder="新浪手机讯4月17日上午消息，近期关于iPhone6传闻格外多，最新一则来自法国网站nowhereelse.fr，因为iPhone6屏幕变大，它的电源键将被放在机身侧面。这种推测来源于几张“iPhone6硅胶壳”图片，“i6”这种写法似乎是中国南方一些附件厂商喜爱的称呼。假设这种保护壳为真，那下一代iPhone最明显的改善就是机身变得更大，并且电源键从机身顶部被转移到了侧面，相信这是为了唤醒手机更方便，现在很多5寸以上大屏手机都采用这种方式。"
              v-model="textarea"
            ></el-input>
          </div>
        </el-row>
        <el-row type="flex" pull="2" push="2" justify="end" class="el-row-stype"
          ><el-button type="primary" @click="startAnaly()"
            >开始分析</el-button
          ></el-row
        >
      </el-col>
    </el-row>
    <!-- 结果展示框 tabs -->
    <el-row type="flex" class="row-bg el-row-stype" justify="center">
      <el-col :span="20" style="text-align: left">
        <el-tabs type="border-card" v-model="activeName">
          <!-- 分词结果 tab -->
          <el-tab-pane name="分词结果">
            <span slot="label">
              <i class="el-icon-date"></i>
              分词结果
            </span>
            <el-row>
              <el-col :span="22">
                <i class="el-icon-date"></i>
                分词结果
              </el-col>
            </el-row>
            <el-divider></el-divider>
            <el-row type="flex" justify="start" class="el-row-tab">
              <el-col :span="16">
                <div v-if="segmentSet.length > 0">
                  <el-tag
                    v-for="item in segmentSet"
                    :key="item.label"
                    effect="light"
                    class="tag-margin"
                    :color="item.color"
                    >{{ item.word }}</el-tag
                  >
                </div>
                <div v-else class="data-empty">没有数据😂</div>
              </el-col>
              <el-col :span="2"></el-col>
              <el-col :span="5" style="padding: 10px">
                <el-row>词性类别图示</el-row>
                <el-row class="el-row-stype">
                  <el-tag
                    v-for="item in segmentItems"
                    :key="item.label"
                    effect="light"
                    class="tag-margin"
                    :color="item.color"
                    >{{ item.label }}</el-tag
                  >
                </el-row>
              </el-col>
              <el-col :span="1"></el-col>
            </el-row>
          </el-tab-pane>
          <el-tab-pane name="实体识别">
            <span slot="label">
              <i class="el-icon-date"></i>
              实体识别
            </span>
            <el-row>
              <el-col :span="22">
                <i class="el-icon-date"></i>
                实体识别
              </el-col>
            </el-row>
            <el-divider></el-divider>
            <el-row type="flex" justify="start" class="el-row-tab">
              <el-col :span="16">
                <div v-if="nounSetData.length > 0">
                  <el-tag
                    v-for="item in nounSetData"
                    :key="item.noun"
                    effect="light"
                    class="tag-margin"
                    :color="item.color"
                    >{{ item.noun }}</el-tag
                  >
                </div>
                <div v-else class="data-empty">没有数据😂</div>
              </el-col>
              <el-col :span="2"></el-col>
              <el-col :span="5" style="padding: 10px">
                <el-row>实体类别图示</el-row>
                <el-row class="el-row-stype">
                  <el-tag
                    v-for="item in nounItems"
                    :key="item.label"
                    effect="light"
                    class="tag-margin"
                    :color="item.color"
                    >{{ item.label }}</el-tag
                  >
                </el-row>
              </el-col>
              <el-col :span="1"></el-col>
            </el-row>
          </el-tab-pane>
          <el-tab-pane name="词频统计">
            <span slot="label">
              <i class="el-icon-date"></i>
              词频统计
            </span>
            <el-row>
              <el-col :span="22">
                <i class="el-icon-date"></i>
                词频统计
              </el-col>
            </el-row>
            <el-divider></el-divider>
            <el-row class="el-row-tab" type="flex" justify="center">
              <el-col :span="16">
                <ve-histogram
                  :data="wordFrequencyData"
                  :settings="wordFrequencySettings"
                  :extend="wordFrequencyExtend"
                  ref="wordFrequency"
                >
                  <!--  词云图无数据状态 -->
                  <div
                    v-show="wordFrequencyData.rows.length === 0"
                    class="data-empty"
                  >
                    没有数据😂
                  </div>
                </ve-histogram>
              </el-col>
              <el-col :span="6">
                <el-form ref="form" :model="topN" label-width="80px">
                  <el-form-item label="topN:"
                    ><el-input-number
                      v-model="topN.n"
                      :step="2"
                    ></el-input-number
                  ></el-form-item>
                  <el-form-item
                    ><el-button type="primary" @click="topNClick"
                      >查找</el-button
                    ></el-form-item
                  >
                  <el-form-item label="结果:"
                    ><el-input
                      type="textarea"
                      v-model="topN.desc"
                      :autosize="{ minRows: 4, maxRows: 999 }"
                    ></el-input
                  ></el-form-item>
                </el-form>
              </el-col>
            </el-row>
          </el-tab-pane>
          <el-tab-pane name="词云图">
            <span slot="label">
              <i class="el-icon-date"></i>
              词云图
            </span>
            <el-row>
              <el-col :span="22">
                <i class="el-icon-date"></i>
                词云图
              </el-col>
            </el-row>
            <el-divider></el-divider>
            <!-- 词云图，使用的 v-charts 因为在tabs中，初始宽度未知的容器内绘制图表时，因为无法获取宽度，所以图表会绘制失败，解决的办法是在容器宽度已知后， 调用echarts的resize方法。-->
            <el-row class="el-row-tab">
              <ve-wordcloud
                :data="wordChartData"
                :settings="wordChartSettings"
                :extend="wordChartExtend"
                ref="wordChart"
              >
                <!--  词云图无数据状态 -->
                <div
                  v-show="wordChartData.rows.length === 0"
                  class="data-empty"
                >
                  没有数据😂
                </div>
              </ve-wordcloud>
            </el-row>
          </el-tab-pane>
          <el-tab-pane name="关键词提取">
            <span slot="label">
              <i class="el-icon-date"></i>
              关键词提取
            </span>
            <el-row>
              <el-col :span="22">
                <i class="el-icon-date"></i>
                关键词提取
              </el-col>
            </el-row>
            <el-divider></el-divider>
            <el-row type="flex" class="el-row-tab">
              <el-col>
                <div v-if="keyWordsData.length > 0">
                  <el-tag
                    v-for="item in keyWordsData"
                    :key="item.label"
                    effect="light"
                    class="tag-margin"
                    :color="item.color"
                    >{{ item.keyWord }}</el-tag
                  >
                </div>
                <div v-else class="data-empty">没有数据😂</div>
              </el-col>
            </el-row>
          </el-tab-pane>
          <el-tab-pane name="情感分析">
            <span slot="label">
              <i class="el-icon-date"></i>
              情感分析
            </span>
            <el-row>
              <el-col :span="22">
                <i class="el-icon-date"></i>
                情感分析
              </el-col>
            </el-row>
            <el-divider></el-divider>
            <el-row class="el-row-tab">
              <ve-pie :data="sentimentAnalyData" ref="sentimentAnaly">
                <!--  无数据状态 -->
                <div
                  v-show="sentimentAnalyData.rows.length === 0"
                  class="data-empty"
                >
                  没有数据😂
                </div>
              </ve-pie>
            </el-row>
          </el-tab-pane>
        </el-tabs>
      </el-col>
    </el-row>
    <!-- 观点提取 				{
					sourceSentence: "运行速度快"
					attrs: [
						{ dimension: "产品体验",attribute: "功能",property: "反应速度",feature:"NULL", sentiment: "运行速度快",polarity: "正面"},
						{ dimension: "产品体验",attribute: "功能",property: "反应速度",feature:"NULL", sentiment: "运行速度快",polarity: "正面"},
						{ dimension: "产品体验",attribute: "功能",property: "反应速度",feature:"NULL", sentiment: "运行速度快",polarity: "正面"}
					]
				},-->
    <el-row
      class="row-bg"
      v-for="(attributes, index) of attributesList"
      :key="index"
      :gutter="12"
    >
      <el-col
        :span="7"
        v-for="(attrrbute, innerindex) in attributes"
        :key="innerindex"
        :offset="innerindex % 2 === 0 ? 4 : 1"
        class="top-margin"
      >
        <el-card class="box-card" shadow="hover">
          <div slot="header" class="clearfix">
            <span>{{ attrrbute.sourceSentence }}</span>
            <el-button style="float: right; padding: 3px 0" type="text"
              >删除</el-button
            >
          </div>
          <el-table :data="attrrbute.attrs" style="width: 100%">
            <el-table-column
              prop="dimension"
              label="一级指标"
            ></el-table-column>
            <el-table-column
              prop="attribute"
              label="二级指标"
            ></el-table-column>
            <el-table-column prop="property" label="三级指标"></el-table-column>
            <el-table-column prop="feature" label="特征"></el-table-column>
            <el-table-column prop="sentiment" label="情感"></el-table-column>
            <el-table-column prop="polarity" label="正负面"></el-table-column>
          </el-table>
        </el-card>
      </el-col>
    </el-row>
  </div>
</template>

<script>
import request from '@/modules/index/utils/request';

export default {
  name: "SingleText",
  data() {
    return {
      loading: false,
      typeCHs: {
        car: "汽车",
        ecommerce: "电商",
        opinion: "舆情",
      },
      activeName: "分词结果",
      textarea: "",
      // 选择类别行业品类的待选框数据
      startAnalyDataOptions: {
        types: [],
        industries: [],
        categories: [],
      },
      // 选择类别行业品类的数据
      startAnalyData: {
        type: "",
        industry: "",
        category: "",
      },
      // 分词结果
      segmentSet: [],
      // 分词颜色表
      segmentTtemsMap: {
        名词: "#488fce",
        时间词: "#c7aee7",
        标点符号: "#ccc",
        介词: "#99cc67",
        字符串: "#96dbf8",
        数词: "#986699",
        副词: "#ffcccb",
        形容词: "#67ccaa",
        量词: "#ff9899",
        动词: "#ffcb99",
        拟声词: "#d07f7f",
        网页链接: "#96dbf8",
        连词: "#8ea4de",
        连语: "#c9aaca",
        代词: "#9acccd",
        助词: "#4dd9e6",
        语气词: "#f48363",
        其他: "#8bc3f5",
      },
      // 分词类别图示
      segmentItems: [
        { label: "名词", color: "#488fce" },
        { label: "时间词", color: "#c7aee7;" },
        { label: "标点符号", color: "#ccc" },
        { label: "介词", color: "#99cc67" },
        { label: "字符串", color: "#96dbf8" },
        { label: "数词", color: "#986699" },
        { label: "副词", color: "#ffcccb" },
        { label: "形容词", color: "#67ccaa" },
        { label: "量词", color: "#ff9899" },
        { label: "动词", color: "#ffcb99" },
        { label: "拟声词", color: "#d07f7f" },
        { label: "网页链接", color: "#96dbf8" },
        { label: "连词", color: "#8ea4de" },
        { label: "连语", color: "#c9aaca" },
        { label: "代词", color: "#9acccd" },
        { label: "助词", color: "#4dd9e6" },
        { label: "语气词", color: "#f48363" },
        { label: "其他", color: "#8bc3f5" },
      ],
      nounSetData: [],
      nounItemsMap: {
        学校: "#d07f7f",
        时间词: "#488fce",
        动物名: "#c7aee7",
        工厂: "#cccccc",
        银行: "#99cc67",
        生物名: "#96dbf8",
        食品: "#986699",
        药品: "#ffcccb",
        地名: "#67ccaa",
        疾病: "#ff9899",
        植物名: "#ffcb99",
        化学品名: "#96dbf8",
        人名: "#8ea4de",
        学术词汇: "#c9aaca",
        公司名: "#9acccd",
        工作: "#4dd9e6",
        医院: "#f48363",
        酒店宾馆: "#bec3cc",
        机构: "#b9eca0",
        物品名: "#b73737",
      },
      nounItems: [
        { label: "学校", color: "#d07f7f" },
        { label: "时间词", color: "#488fce" },
        { label: "动物名", color: "#c7aee7" },
        { label: "工厂", color: "#cccccc" },
        { label: "银行", color: "#99cc67" },
        { label: "生物名", color: "#96dbf8" },
        { label: "食品", color: "#986699" },
        { label: "药品", color: "#ffcccb" },
        { label: "地名", color: "#67ccaa" },
        { label: "疾病", color: "#ff9899" },
        { label: "植物名", color: "#ffcb99" },
        { label: "化学品名", color: "#96dbf8" },
        { label: "人名", color: "#8ea4de" },
        { label: "学术词汇", color: "#c9aaca" },
        { label: "公司名", color: "#9acccd" },
        { label: "工作", color: "#4dd9e6" },
        { label: "医院", color: "#f48363" },
        { label: "酒店宾馆", color: "#bec3cc" },
        { label: "机构", color: "#b9eca0" },
        { label: "物品名", color: "#b73737" },
      ],
      topN: {
        n: 3,
        desc: "",
        // 我们需要的是topN,所以搞一个所有的把数据都存在这里来
        allrows: [],
      },
      // 词频图的数据定义
      wordFrequencyData: {
        columns: ["word", "count"],
        // 词频的数据结构是 [{word:"xx",count:44}...]
        rows: [],
      },
      // 词频图一些参数配置，柱状图 https://v-charts.js.org/#/histogram
      wordFrequencySettings: {
        // 左右坐标轴标题
        // yAxisName:["词频topN"],
        // 修改别名，数据的名字一般都是英文，我们需要对应为中文，就是这个意思咯
        labelMap: {
          count: "词频topN",
        },
      },
      // 词频图的额外参数，参考： https://v-charts.js.org/#/props-demo2
      wordFrequencyExtend: {},
      // 词云图的数据定义
      wordChartData: {
        columns: ["word", "count"],
        rows: [],
      },
      // 词云图配置
      wordChartSettings: {
        // 设置词云图的字体大小范围 最小 默认为 12 最大 默认为 60
        sizeMin: 12,
        sizeMax: 60,
      },
      // 词云图的额外参数，参考： https://v-charts.js.org/#/props-demo2
      wordChartExtend: {
        series: {
          // 词云图参数配置 参考 https://github.com/ecomfe/echarts-wordcloud
          rotationRange: [0, 0],
          width: "100%",
          height: "100%",
        },
      },
      // 情感分析,饼图数据
      sentimentAnalyData: {
        columns: ["sentimentType", "count"],
        rows: [],
      },
      // 关键词提取数据
      keyWordsData: [],
      // 观点提取数据
      attributesList: [],
    };
  },
  computed: {},
  // 页面加载完成执行的方法
  mounted() {
    /*
    // 通过 api 获取类别的待选数据
    request('/label/getType', {
      method: 'post',
    }).then((res) => {
    // http.post("/label/getType").then((res) => {
      var arrayData = Object.values(JSON.parse(res.data.result))[0];
      var typeArray = new Array();
      for (var i = 0; i < arrayData.length; i++) {
        var typeCH = this.typeCHs[arrayData[i]];
        var arr = {
          name: typeCH == null ? arrayData[i] : typeCH,
          option: arrayData[i],
        };
        typeArray[i] = arr;
      }
      this.startAnalyDataOptions.types = typeArray;
      if (arrayData.length > 0) {
        this.startAnalyData.type = arrayData[0];
      }
    });
    */
  },
  methods: {
    hasOwn (target, key) {
      return Object.hasOwnProperty.call(target, key);
    },
    topNClick() {
      let that = this;
      // 根据 n来 构造 图 和 显示的数
      if (that.topN.allrows.length === 0) {
        this.$message.warning("错了哦，你还没提交分析呢，现在啥都看不到");
      } else {
        that.wordFrequencyData.rows = listTopN(that.topN.n, that.topN.allrows);
        that.topN.desc = that.wordFrequencyData.rows.reduce(
          // pre 前一次的结果 , cru 现在的值, index 索引, allarr 整个数组 initialValue 可选。传递给函数的初始值
          // (pre,cur,index,allarr) =>{},initialValue
          (pre, cur) => {
            return pre + cur.word + ":\t" + cur.count + "\n";
          },
          ""
        );
      }
    },
    async startAnaly() {
      let that = this;
      if (this.textarea == "" || this.textarea == null) {
        this.$message({ type: 'warning', message: '分析句子不能为空' });
        return;
      }
      var paramsOne = {
        // type: this.startAnalyData.type,
        comment: this.textarea,
      };

      this.loading = true;
      try {
        const res = await this.$store.dispatch('openAbilityPlatformPredictTaskOnecommet', paramsOne);
        // 分词结果封装
        that.segmentSet = res.data.data.segmentSet.map(
          // (value,index,allarr) => { value 是值， index 索引序号， allarr 就是整个 res.data.segmentSet
          (value) => {
            return {
              color: that.segmentTtemsMap[value.type],
              word: value.word,
            };
          }
        );
        // 词云图数据载入
        that.wordChartData.rows = res.data.data.frequencySet;
        // 词频图的数据载入,传入的是已经排好序的，方便后面 top n 调用
        that.topN.allrows = res.data.data.frequencySet.sort((a, b) => {
          return b.count - a.count;
        });
        // 根据 n来 构造 图 和 显示的数
        that.wordFrequencyData.rows = listTopN(that.topN.n, that.topN.allrows);
        that.topN.desc = that.wordFrequencyData.rows.reduce(
          // pre 前一次的结果 , cru 现在的值, index 索引, allarr 整个数组 initialValue 可选。传递给函数的初始值
          // (pre,cur,index,allarr) =>{},initialValue
          (pre, cur) => {
            return pre + cur.word + ":\t" + cur.count + "\n";
          },
          ""
        );
        // 情感分析的数据载入 需要的数据格式 [{'sentimentType': '1/6', 'count': 4593 }。。。]
        let sentimentMap = {};
        res.data.data.sentimentList.forEach((value) => {
          // if (sentimentMap.hasOwnProperty(value.sentiment)) {
          if (this.hasOwn(sentimentMap, value.sentiment)) {
            sentimentMap[value.sentiment] = sentimentMap[value.sentiment] + 1;
          } else {
            sentimentMap[value.sentiment] = 1;
          }
        });
        // Object.keys(sentimentMap) 获取对象所有的属性 也就是 key
        that.sentimentAnalyData.rows = Object.keys(sentimentMap).map((key) => {
          // 需要的数据格式 [{'sentimentType': '1/6', 'count': 4593 }。。。]
          return { sentimentType: key, count: sentimentMap[key] };
        });
        // 名词识别数据载入
        that.nounSetData = res.data.data.nounSet.map(
          // (value,index,allarr) => { value 是值， index 索引序号， allarr 就是整个 res.data.segmentSet
          (value) => {
            return { color: that.nounItemsMap[value.type], noun: value.word };
          }
        );
      } catch (e) {
        console.error(e);
      }
      try {
        const res = await this.$store.dispatch('openAbilityPlatformPredictTaskOneExtraComment', paramsOne);
        const result = res.data || {};
        if (result.success) {
          that.keyWordsData = result.data.keywords.map((keyword) => {
            return { keyWord: keyword, color: Color() };
          });
        } else {
          that.keyWordsData = [];
        }
      } catch (e) {
        console.error(e);
      }
      this.loading = false;
    },
  },
  // 在一个初始宽度未知的容器内绘制图表时，因为无法获取宽度，所以图表会绘制失败，解决的办法是在容器宽度已知后， 调用echarts的resize方法。
  watch: {
    // 类别选项选择/变化了后,行业数据需要刷新,品类全部删除
    "startAnalyData.type": function (newType) {
      //监听特定的属性，这样写

      // 通过 api 获取行业的数据
      request('/label/getIndustry', {
        method: 'post',
        data: {
          type: newType
        }
      })
      // http
        // .post("/label/getIndustry", { type: newType }) // TODO 这里暂时还没有接口，等后台提供，肯定要传参： 类别：
        .then((res) => {
          // 加载行业数据
          var arrayData = Object.values(res.data.result)[0];
          var industryArray = new Array();
          for (var i = 0; i < arrayData.length; i++) {
            var arr = {
              industry: arrayData[i],
              option: arrayData[i],
            };
            industryArray[i] = arr;
          }
          this.startAnalyDataOptions.industries = industryArray;
          // 清空品类数据
          this.startAnalyDataOptions.categories = [];
          if (arrayData.length > 0) {
            this.startAnalyData.industry = arrayData[0];
          }
        });
    },
    // 行业选项选择/变化了后,品类数据需要刷新
    "startAnalyData.industry": function (newIndustry) {
      //监听特定的属性，这样写

      // 通过 api 获取品类的数据
      request('/label/getDomain', {
        method: 'post',
        data: {
          type: this.startAnalyData.type,
          industry: newIndustry,
        }
      })
      // http
      //   .post("/label/getDomain", {
      //     type: this.startAnalyData.type,
      //     industry: newIndustry,
      //   }) // TODO 这里暂时还没有接口，等后台提供，肯定要传参： 类别： 行业：
        .then((res) => {
          var arrayData = Object.values(res.data.result)[0];
          var domainArray = new Array();
          for (var i = 0; i < arrayData.length; i++) {
            var arr = {
              category: arrayData[i],
              option: arrayData[i],
            };
            domainArray[i] = arr;
          }
          // 加载品类数据
          this.startAnalyDataOptions.categories = domainArray;
          if (arrayData.length > 0) {
            this.startAnalyData.category = arrayData[0];
          }
        });
    },
    activeName(v) {
      this.$nextTick(() => {
        if (v === "词云图") {
          this.$refs[`wordChart`].echarts.resize();
        }
        if (v === "词频统计") {
          this.$refs[`wordFrequency`].echarts.resize();
        }
        if (v === "情感分析") {
          this.$refs[`sentimentAnaly`].echarts.resize();
        }
      });
    },
  },
};
function listTopN(n, l) {
  // 如果 n 太大了,就返回所有的
  if (l.length < n) {
    return l;
  } else {
    return l.slice(0, n);
  }
}
//颜色对象
function Color() {
  return "#" + Math.floor(Math.random() * 16777215).toString(16);
}
</script>

<!-- Add "scoped" attribute to limit CSS to this components only -->
<style scoped>
.row-bg {
  background-color: #f9fafc;
  padding: 20px;
}
.el-row-stype {
  margin-top: 20px;
  padding: 0.25rem;
}
.tag-margin {
  margin: 0 5px 5px 0;
  color: #5c3317;
}
.top-margin {
  margin-top: 0.75rem;
}
.el-row-tab {
  min-height: 25rem;
}
/* 自定义 v-charts 没有数据显示的状态 */
.data-empty {
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  bottom: 0;
  display: flex;
  justify-content: center;
  align-items: center;
  background-color: rgba(255, 255, 255, 0.7);
  color: #888;
  font-size: 14px;
}
.clearfix:before,
.clearfix:after {
  display: table;
  content: "";
}
.clearfix:after {
  clear: both;
}
#SingleText {
  text-align: center;
}
</style>
